package com.common.config;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.common.base.BaseConstant;
import com.common.util.RedisUtil;
import com.common.vo.ResultVo;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 删除redis缓存
     */
    private void delCache(String tokenValue,String loginId){
        RedisUtil redisUtil= SpringUtil.getBean(RedisUtil.class);
        String lastActivity = BaseConstant.cachePrefix+"last-activity:"+tokenValue;
        String session = BaseConstant.cachePrefix+"session:"+loginId;
        String token = BaseConstant.tokenCachePrefix+tokenValue;
        if (redisUtil.hasKey(lastActivity)){
            redisUtil.del(lastActivity);
        }
        if (redisUtil.hasKey(session)){
            redisUtil.del(session);
        }
        if (redisUtil.hasKey(token)){
            redisUtil.del(token);
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
        response.setHeader("Access-Control-Allow-Origin", (request).getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        // 获取当前token（这个token获取的是请求头的token，也可以用 request 获取）
        String tokenValue = StpUtil.getTokenValue();
        // 根据token获取用户id（这里如果找不到id直接返回null，不会报错）
        String loginId = (String) StpUtil.getLoginIdByToken(tokenValue);
        //判断token是否过期
        if (!StpUtil.isLogin()){
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(1003);
            resultVo.setMessage("用户未登录，请进行登录");
            response.getWriter().write(JSONUtil.toJsonStr(resultVo));
            //token已经过期，但是redis中可能还存在，所以要删除
            delCache(tokenValue,loginId);
            return false;
        }
        //判断token的创建时间是否大于2小时，如果是的话则需要刷新token
        long time = System.currentTimeMillis() - StpUtil.getSession().getCreateTime();
        long hour = time/1000/(60 * 60);
        if (hour>2){
            //这里要生成新的token的话，要先退出再重新登录
            //根据当前登录id（和设备）退出登录
            StpUtil.logout(loginId);
            //然后再重新登录，生成新的token
            StpUtil.login(loginId);
            String newToken = StpUtil.getTokenValue();
            System.err.println("生成的新token："+ newToken);
            response.setHeader("sa-token-demo", newToken);
        }
        // 获取过期时间
        long tokenTimeout = StpUtil.getTokenTimeout();
        //token没过期，过期时间不是-1的时候，每次请求都刷新过期时间
        if (tokenTimeout != -1){
            SaTokenDao saTokenDao = SaManager.getSaTokenDao();
            saTokenDao.updateSessionTimeout(StpUtil.getSession().getId(),3600);
            saTokenDao.updateTimeout(BaseConstant.tokenCachePrefix+tokenValue,3600);
            saTokenDao.updateTimeout(BaseConstant.cachePrefix+"last-activity:"+tokenValue,3600);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}
